package com.ebrg.secure9.activity.setup;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.ebrg.secure9.Account;
import com.ebrg.secure9.Preferences;
import com.ebrg.secure9.activity.ChooseKey;
import com.ebrg.secure9.activity.K9Activity;
import com.ebrg.secure9.activity.MessageCompose;
import com.ebrg.secure9.mail.Address;
import com.ebrg.secure9.mail.MessagingException;
import com.ebrg.secure9.mail.security.Hash;
import com.ebrg.secure9.mail.security.Keys;
import com.ebrg.secure9.R;

public class EncryptionManageKey extends K9Activity implements OnClickListener{
	private Account mAccount;
	private static final String EXTRA_ACCOUNT = "account";
	private EditText localEmail;
	private EditText remoteEmail;
	private Button revokeButton;
	private Button deleteButton;
	public static String remoteEmailSource;
	public static Address[] otherParty;
	private boolean pinMatch;;
	private EditText input;
	private char[] pinInput;


	public static void actionManageKey(Activity context, Account account, String chosen)
	{
		remoteEmailSource = chosen;
		Intent i = new Intent(context, EncryptionManageKey.class);
		i.setAction(Intent.ACTION_EDIT);
		i.putExtra("account", account.getUuid());
		context.startActivity(i);
	}


	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		String accountUuid = getIntent().getStringExtra("account");
		mAccount = Preferences.getPreferences(this).getAccount(accountUuid);

		setContentView(R.layout.encryption_manage_key);
		this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 

		if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_ACCOUNT))
		{
			accountUuid = savedInstanceState.getString(EXTRA_ACCOUNT);
			mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
		}


		localEmail = (EditText)findViewById(R.id.local_email);
		localEmail.setText(mAccount.getEmail());
		localEmail.setFocusable(false);
		localEmail.setEnabled(false);

		revokeButton = (Button)findViewById(R.id.revoke_key);
		revokeButton.setOnClickListener(this);
		revokeButton.setEnabled(true);

		//If diffie-hellman setup is not complete
		if(remoteEmailSource.contains("(Incomplete) "))
		{			
			remoteEmailSource = remoteEmailSource.replaceAll("(Incomplete)", "");
			remoteEmailSource = remoteEmailSource.replace("() ", "");
			revokeButton.setEnabled(false);
			Toast.makeText(EncryptionManageKey.this, "This key will become usable when the other party"
					+ " responds with their public key.", Toast.LENGTH_LONG).show();
			Toast.makeText(EncryptionManageKey.this, "This key will become usable when the other party"
					+ " responds with their public key.", Toast.LENGTH_SHORT).show();
		}

		deleteButton = (Button)findViewById(R.id.delete_key);
		deleteButton.setOnClickListener(this);
		deleteButton.setEnabled(true);

		remoteEmail = (EditText)findViewById(R.id.remote_email);
		remoteEmail.setText(remoteEmailSource);
		remoteEmail.setEnabled(false);
		remoteEmail.setFocusable(false);
		remoteEmail.clearFocus();
		
		//Check for pin file
		pinMatch = Hash.pinExists(this, mAccount.getEmail().toLowerCase());			
	}

	@Override
	public void onResume()
	{
		super.onResume();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		return super.onKeyDown(keyCode, event);
	}

	private void revokeKey(){
		int icon = R.drawable.key_bad;
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Confirm Action");
		alert.setMessage("Are you sure you want to revoke this key and alert " + remoteEmail.getText().toString() + 
		" of this action?");

		//If pin file is found, require pin confirmation, else just yes/no confirm
		if(pinMatch)
		{
			// Set an EditText view to get user input 
			input = new EditText(this);
			input.setInputType(InputType.TYPE_CLASS_PHONE);
			input.setTransformationMethod			
			(android.text.method.PasswordTransformationMethod.getInstance());
			alert.setView(input);
			alert.setMessage("Enter your PIN to confirm key revocation.  This will send an alert to " + 
					remoteEmail.getText().toString() + ".");
			icon = R.drawable.pin;

		}
		alert.setPositiveButton(R.string.yes_action, new DialogInterface.OnClickListener() 
		{
			public void onClick(DialogInterface dialog, int whichButton) 
			{
				if(pinMatch)				
					verifyPin("revoke"); //Verfiy pin if present
				
				else
				{					
					EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
							remoteEmailSource + EncryptionManageKey.this.getString(R.string.complete_key_file_type)).toLowerCase());	
									
					otherParty = MessageCompose.getAddressFromString(remoteEmail.getText().toString());

					try 
					{
						//Email revocation alert
						MessageCompose.revokeKey(EncryptionManageKey.this, otherParty, mAccount); 
						Toast.makeText(EncryptionManageKey.this, "Key Deleted, revocation complete.", Toast.LENGTH_LONG).show();
					} 
					catch (MessagingException e) 
					{
						//should never happen
					}
					//Return to key list
					Intent intent = new Intent(EncryptionManageKey.this, ChooseKey.class);
					intent.putExtra(ChooseKey.EXTRA_ACCOUNT, mAccount.getUuid());
					startActivityForResult(intent, 2);
					finish();
				}

			}

		});

		alert.setNegativeButton(R.string.no_action, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				// Canceled.

			}
		});

		alert.setIcon(icon);
		alert.show();



	}


	private void deleteKey()
	{
		int icon = R.drawable.key_bad;
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Confirm Action");
		alert.setMessage(R.string.confirm_delete_key);

		//If account pin file is found
		if(pinMatch)
		{
			// Set an EditText view to get user input 
			input = new EditText(this);
			input.setInputType(InputType.TYPE_CLASS_PHONE);
			input.setTransformationMethod	
			(android.text.method.PasswordTransformationMethod.getInstance());
			alert.setView(input);
			alert.setMessage(R.string.pin_confirm_delete_key);			
			icon = R.drawable.pin;
		}
		alert.setPositiveButton(R.string.yes_action, new DialogInterface.OnClickListener() 
		{
			public void onClick(DialogInterface dialog, int whichButton) 
			{
				if(pinMatch)
					verifyPin("delete"); //Delete key, no revocation alert
				
				else
				{
					//Delete key file
					EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
							remoteEmail.getText().toString()+ EncryptionManageKey.this.getString(R.string.complete_key_file_type)).toLowerCase());	
					EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
							remoteEmail.getText().toString()+ EncryptionManageKey.this.getString(R.string.initial_key_file_type)).toLowerCase());	

					Toast.makeText(EncryptionManageKey.this, R.string.key_deleted, Toast.LENGTH_LONG).show();
					
					//Return to key list
					Intent intent = new Intent(EncryptionManageKey.this, ChooseKey.class);
					intent.putExtra(ChooseKey.EXTRA_ACCOUNT, mAccount.getUuid());
					startActivityForResult(intent, 2);
					finish();
				}

			}

		});

		alert.setNegativeButton(R.string.no_action, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				// Canceled.

			}
		});

		alert.setIcon(icon);
		alert.show();
	}

	private void verifyPin(String action)
	{

		FileInputStream fis;
		try 
		{
			fis = openFileInput((mAccount.getEmail().toLowerCase()) + this.getString(R.string.legacy_pin_file_type));
			BufferedReader in = new BufferedReader(new InputStreamReader(fis));	
			char[] pinFromFile = in.readLine().toCharArray();
			
			//Read in input pin (complex because we're going by chars rather than a string)
			char[] pinInput = new char[input.getText().length()];
			for(int i = 0; i < input.getText().length(); i++)
				pinInput[i] = input.getText().charAt(i);
			
			boolean match = false;
			if(Arrays.equals(pinFromFile, pinInput))
				match = true;

			if (match && action.equals("delete"))
			{								
				//Delete key file
				EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
						remoteEmail.getText().toString()+ EncryptionManageKey.this.getString(R.string.complete_key_file_type)).toLowerCase());	
				EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
						remoteEmail.getText().toString()+ EncryptionManageKey.this.getString(R.string.initial_key_file_type)).toLowerCase());
				match = false;

				Toast.makeText(EncryptionManageKey.this, R.string.key_deleted, Toast.LENGTH_LONG).show();


				//Return to key list
				Intent intent = new Intent(EncryptionManageKey.this, ChooseKey.class);
				intent.putExtra(ChooseKey.EXTRA_ACCOUNT, mAccount.getUuid());
				startActivityForResult(intent, 2);

			}

			else if (match && action.equals("revoke"))
			{
				EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
						remoteEmailSource + this.getString(R.string.complete_key_file_type)).toLowerCase());	
				
				Keys.refreshKeys(EncryptionManageKey.this);
				
				otherParty = MessageCompose.getAddressFromString(remoteEmail.getText().toString());

				try 
				{
					MessageCompose.revokeKey(EncryptionManageKey.this, otherParty, mAccount);
				} 
				catch (MessagingException e) 
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				Toast.makeText(EncryptionManageKey.this, "Key Deleted, revocation complete.", Toast.LENGTH_LONG).show();
				//Return to key list
				Intent intent = new Intent(EncryptionManageKey.this, ChooseKey.class);
				intent.putExtra(ChooseKey.EXTRA_ACCOUNT, mAccount.getUuid());
				startActivityForResult(intent, 2);
			}
			else			
				Toast.makeText(EncryptionManageKey.this,R.string.pin_incorrect,Toast.LENGTH_LONG).show();
			

			if(pinInput !=  null)
				Arrays.fill(pinInput, '0');
			if(pinFromFile !=  null)
				Arrays.fill(pinFromFile, '0');

		} 
		catch (FileNotFoundException e) 
		{
			//No pin, need to look for and try with pin2.
			try 
			{
				fis = openFileInput((mAccount.getEmail().toLowerCase()) + this.getString(R.string.hashed_pin_file_type));
				BufferedReader in = new BufferedReader(new InputStreamReader(fis));	
				String hashFromFile = in.readLine();
				String storedRand = Hash.getRandom(hashFromFile, input.getText().length(), this);
				String storedStatic = Hash.getStatic(hashFromFile, input.getText().length(), this);

				char[] inputPin = new char[input.getText().length()];
				for(int i = 0; i < input.getText().length(); i++)
					inputPin[i] = input.getText().charAt(i);
				
				String inputHash = Hash.verify(mAccount.getEmail(), 
						inputPin, storedRand, storedStatic);
				
				boolean match = false;
				if(inputHash.equals(hashFromFile))
					match = true;	

				if (match && action.equals("delete"))
				{								
					//Delete key file
					EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
							remoteEmail.getText().toString()+ EncryptionManageKey.this.getString(R.string.complete_key_file_type)).toLowerCase());	
					EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
							remoteEmail.getText().toString()+ EncryptionManageKey.this.getString(R.string.initial_key_file_type)).toLowerCase());
					match = false;

					Toast.makeText(EncryptionManageKey.this, R.string.key_deleted, Toast.LENGTH_LONG).show();

					//Refresh key list for display
					Keys.refreshKeys(EncryptionManageKey.this);

					//Return to key list
					Intent intent = new Intent(EncryptionManageKey.this, ChooseKey.class);
					intent.putExtra(ChooseKey.EXTRA_ACCOUNT, mAccount.getUuid());
					startActivityForResult(intent, 2);

				}

				else if (match && action.equals("revoke"))
				{
					EncryptionManageKey.this.deleteFile((localEmail.getText().toString() + 
							remoteEmailSource + EncryptionManageKey.this.getString(R.string.complete_key_file_type)).toLowerCase());	
					
					Keys.refreshKeys(EncryptionManageKey.this);
					
					otherParty = MessageCompose.getAddressFromString(remoteEmail.getText().toString());

					try 
					{
						MessageCompose.revokeKey(EncryptionManageKey.this, otherParty, mAccount);
					} 
					catch (MessagingException e1) 
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					Toast.makeText(EncryptionManageKey.this, "Key Deleted, revocation complete.", Toast.LENGTH_LONG).show();
					//Return to key list
					Intent intent = new Intent(EncryptionManageKey.this, ChooseKey.class);
					intent.putExtra(ChooseKey.EXTRA_ACCOUNT, mAccount.getUuid());
					startActivityForResult(intent, 2);
				}
				else
					Toast.makeText(EncryptionManageKey.this,R.string.pin_incorrect,Toast.LENGTH_LONG).show();
				

				if(pinInput != null)
					Arrays.fill(pinInput, '0');

			} catch (FileNotFoundException e1) {
				Toast.makeText(EncryptionManageKey.this,R.string.error_key_not_found,Toast.LENGTH_LONG).show();

			} catch (IOException e1) {
				Toast.makeText(EncryptionManageKey.this,R.string.error_key_io,Toast.LENGTH_LONG).show();
			}
		} catch (IOException e) {
			Toast.makeText(EncryptionManageKey.this,R.string.error_key_io,Toast.LENGTH_LONG).show();
		}
	}


	@Override
	public void onSaveInstanceState(Bundle outState)
	{
		super.onSaveInstanceState(outState);
		outState.putSerializable(EXTRA_ACCOUNT, mAccount.getUuid());
	}

	public void onClick(View v)
	{
		switch (v.getId())
		{
		case R.id.revoke_key:

			revokeKey();

			break;

		case R.id.delete_key:
			deleteKey();
			break;
		}
	}






}
